import React, { Component } from 'react';
import * as PropTypes from 'prop-types';
import { graphql, createFragmentContainer } from 'react-relay';
import { Formik, Form, Field } from 'formik';
import withStyles from '@mui/styles/withStyles';
import { compose, pipe, pick } from 'ramda';
import * as Yup from 'yup';
import MenuItem from '@mui/material/MenuItem';
import inject18n from '../../../../components/i18n';
import TextField from '../../../../components/TextField';
import { SubscriptionFocus } from '../../../../components/Subscription';
import { commitMutation } from '../../../../relay/environment';
import SelectField from '../../../../components/SelectField';

const styles = (theme) => ({
  drawerPaper: {
    minHeight: '100vh',
    width: '50%',
    position: 'fixed',
    overflow: 'hidden',

    transition: theme.transitions.create('width', {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
    padding: '30px 30px 30px 30px',
  },
  createButton: {
    position: 'fixed',
    bottom: 30,
    right: 30,
  },
  importButton: {
    position: 'absolute',
    top: 30,
    right: 30,
  },
});

const vulnerabilityMutationFieldPatch = graphql`
  mutation VulnerabilityEditionDetailsFieldPatchMutation(
    $id: ID!
    $input: [EditInput]!
  ) {
    vulnerabilityEdit(id: $id) {
      fieldPatch(input: $input) {
        ...VulnerabilityEditionDetails_vulnerability
        ...Vulnerability_vulnerability
      }
    }
  }
`;

export const vulnerabilityEditionDetailsFocus = graphql`
  mutation VulnerabilityEditionDetailsFocusMutation(
    $id: ID!
    $input: EditContext!
  ) {
    vulnerabilityEdit(id: $id) {
      contextPatch(input: $input) {
        id
      }
    }
  }
`;

const vulnerabilityValidation = () => Yup.object().shape({
  x_opencti_base_score: Yup.number(),
  x_opencti_base_severity: Yup.string().nullable(),
  x_opencti_attack_vector: Yup.string().nullable(),
  x_opencti_integrity_impact: Yup.string().nullable(),
  x_opencti_availability_impact: Yup.string().nullable(),
  x_opencti_confidentiality_impact: Yup.string().nullable(),
});

class VulnerabilityEditionDetailsComponent extends Component {
  handleChangeFocus(name) {
    commitMutation({
      mutation: vulnerabilityEditionDetailsFocus,
      variables: {
        id: this.props.vulnerability.id,
        input: {
          focusOn: name,
        },
      },
    });
  }

  handleSubmitField(name, value) {
    vulnerabilityValidation()
      .validateAt(name, { [name]: value })
      .then(() => {
        commitMutation({
          mutation: vulnerabilityMutationFieldPatch,
          variables: {
            id: this.props.vulnerability.id,
            input: { key: name, value: value || '' },
          },
        });
      })
      .catch(() => false);
  }

  render() {
    const { t, vulnerability, context } = this.props;
    const initialValues = pipe(
      pick([
        'x_opencti_base_score',
        'x_opencti_base_severity',
        'x_opencti_attack_vector',
        'x_opencti_integrity_impact',
        'x_opencti_availability_impact',
        'x_opencti_confidentiality_impact',
      ]),
    )(vulnerability);
    return (
      <Formik
        enableReinitialize={true}
        initialValues={initialValues}
        validationSchema={vulnerabilityValidation()}
        onSubmit={() => true}
      >
        {() => (
          <Form style={{ margin: '20px 0 20px 0' }}>
            <Field
              component={TextField}
              variant="standard"
              name="x_opencti_base_score"
              label={t('CVSS3 - Score')}
              fullWidth={true}
              type="number"
              step="0.1"
              onFocus={this.handleChangeFocus.bind(this)}
              onSubmit={this.handleSubmitField.bind(this)}
              helperText={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_base_score"
                />
              }
            />
            <Field
              component={SelectField}
              variant="standard"
              name="x_opencti_base_severity"
              label={t('CVSS3 - Severity')}
              fullWidth={true}
              containerstyle={{ width: '100%', margin: '20px 0 0 0' }}
              onFocus={this.handleChangeFocus.bind(this)}
              onChange={this.handleSubmitField.bind(this)}
              helpertext={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_base_severity"
                />
              }
            >
              <MenuItem value="CRITICAL">{t('CRITICAL')}</MenuItem>
              <MenuItem value="HIGH">{t('HIGH')}</MenuItem>
              <MenuItem value="MEDIUM">{t('MEDIUM')}</MenuItem>
              <MenuItem value="LOW">{t('LOW')}</MenuItem>
              <MenuItem value="Unknown">{t('Unknown')}</MenuItem>
            </Field>
            <Field
              component={TextField}
              variant="standard"
              name="x_opencti_attack_vector"
              label={t('CVSS3 - Attack vector')}
              fullWidth={true}
              style={{ marginTop: 20 }}
              onFocus={this.handleChangeFocus.bind(this)}
              onSubmit={this.handleSubmitField.bind(this)}
              helperText={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_attack_vector"
                />
              }
            />
            <Field
              component={TextField}
              variant="standard"
              name="x_opencti_integrity_impact"
              label={t('CVSS3 - Integrity impact')}
              fullWidth={true}
              style={{ marginTop: 20 }}
              onFocus={this.handleChangeFocus.bind(this)}
              onSubmit={this.handleSubmitField.bind(this)}
              helperText={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_integrity_impact"
                />
              }
            />
            <Field
              component={TextField}
              variant="standard"
              name="x_opencti_availability_impact"
              label={t('CVSS3 - Availability impact')}
              fullWidth={true}
              style={{ marginTop: 20 }}
              onFocus={this.handleChangeFocus.bind(this)}
              onSubmit={this.handleSubmitField.bind(this)}
              helperText={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_availability_impact"
                />
              }
            />
            <Field
              component={TextField}
              variant="standard"
              name="x_opencti_confidentiality_impact"
              label={t('CVSS3 - Confidentiality impact')}
              fullWidth={true}
              style={{ marginTop: 20 }}
              onFocus={this.handleChangeFocus.bind(this)}
              onSubmit={this.handleSubmitField.bind(this)}
              helperText={
                <SubscriptionFocus
                  context={context}
                  fieldName="x_opencti_confidentiality_impact"
                />
              }
            />
          </Form>
        )}
      </Formik>
    );
  }
}

VulnerabilityEditionDetailsComponent.propTypes = {
  classes: PropTypes.object,
  theme: PropTypes.object,
  t: PropTypes.func,
  vulnerability: PropTypes.object,
  context: PropTypes.array,
};

const VulnerabilityEditionDetails = createFragmentContainer(
  VulnerabilityEditionDetailsComponent,
  {
    vulnerability: graphql`
      fragment VulnerabilityEditionDetails_vulnerability on Vulnerability {
        id
        x_opencti_base_score
        x_opencti_base_severity
        x_opencti_attack_vector
        x_opencti_integrity_impact
        x_opencti_availability_impact
        x_opencti_confidentiality_impact
      }
    `,
  },
);

export default compose(
  inject18n,
  withStyles(styles, { withTheme: true }),
)(VulnerabilityEditionDetails);
